#include "PWM.h"
#include "stm32f10x_tim.h" 
#include "Delay.h"          
#include "stdint.h"        


static uint16_t PWM_Target_ARR = 24;    // 初始ARR值，2Hz
static uint8_t  PWM_Breath_CCR = 0;     // 呼吸灯亮度
static int8_t   PWM_Breath_Dir = 1;     // 亮度渐变方向（1=渐亮，-1=渐暗）
static const uint8_t PWM_Step = 1;      // 最小步长，定为1
static const float PWM_DELAY_Time = 0.01f; // 每次延时时间，10ms



void PWM_Init(void)
{
   
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 


    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;       // 复用推挽
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;             
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //时基单元
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_TimeBaseStructure.TIM_Period = PWM_Target_ARR;    // 自动重装载值 2Hz
    TIM_TimeBaseStructure.TIM_Prescaler = 7199;           // 预分频系数：72MHz/(7199+1)=10kHz
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;      
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    //比较单元
    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_OCStructInit(&TIM_OCInitStructure); 
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
    TIM_OCInitStructure.TIM_Pulse = 0; 
    TIM_OC1Init(TIM2, &TIM_OCInitStructure); 

  
    TIM_Cmd(TIM2, ENABLE); 
    TIM_CtrlPWMOutputs(TIM2, ENABLE); 
}


//设置PWM比较值
void PWM_SetCompare1(uint16_t Compare)
{
    // 限制CCR值的范围：0到当前ARR
    if (Compare > PWM_GetCurrentARR())
        Compare = PWM_GetCurrentARR(); 
    if (Compare < 0)
        Compare = 0; 

    TIM_SetCompare1(TIM2, Compare); 
}


// 动态呼吸灯频率1到50
void PWM_SetBreathFreq(uint8_t TargetFreq)
{
    
    if (TargetFreq < 1)
        TargetFreq = 1;    // 下限：1Hz
    if (TargetFreq > 50)
        TargetFreq = 50;   // 上限：50Hz

    // ARR = 1/(2×频率×每步延时) - 1）
    // 原理：单个呼吸周期 = 2×ARR×每步延时（CCR从0→ARR→0，共2×ARR步，每步延时10ms）
    uint16_t Calculated_ARR = (uint16_t)(1 / (2 * TargetFreq * PWM_DELAY_Time)) - 1;

    // 限制ARR值范围
    if (Calculated_ARR > 4999) 
        Calculated_ARR = 4999;
    if (Calculated_ARR < 1) 
        Calculated_ARR = 1;

    // 更新目标ARR值并应用到TIM2
    PWM_Target_ARR = Calculated_ARR;
    TIM_SetAutoreload(TIM2, PWM_Target_ARR);

    
    PWM_Breath_CCR = 0;          // 亮度从最暗开始
    PWM_Breath_Dir = 1;          // 方向改为渐亮，更自然
    PWM_SetCompare1(PWM_Breath_CCR); // 立即应用新亮度，避免残留旧亮度
}


// 获取当前呼吸灯频率（给OLED显示和串口响用的）
uint8_t PWM_GetFreq(void)
{
    // 由当前ARR值反推频率,= 1/(2×(ARR+1)×每步延时)上面的公式
    return (uint8_t)(1 / (2 * (PWM_GetCurrentARR() + 1) * PWM_DELAY_Time));
}



uint16_t PWM_GetCurrentARR(void)
{
    return TIM2->ARR;  
}



void PWM_Breath_Loop(void)
{
    // 占空比每次加的值为：方向乘以1，PWM_STEP就是1
    PWM_Breath_CCR += PWM_Breath_Dir * PWM_Step;

    
    if (PWM_Breath_CCR >= PWM_GetCurrentARR())
    {
        PWM_Breath_CCR = PWM_GetCurrentARR(); // 亮度上限：ARR值（LED最亮）
        PWM_Breath_Dir = -1;                  // 切换方向：渐暗
    }
    else if (PWM_Breath_CCR <= 0)
    {
        PWM_Breath_CCR = 0;                   // 亮度下限：0（LED最暗）
        PWM_Breath_Dir = 1;                   // 切换方向：渐亮
    }

    //使用当前亮度
    PWM_SetCompare1(PWM_Breath_CCR);

    Delay_ms(10); 
}
